# 导入必要的模块
import random
import string
import tkinter as tk
from tkinter import ttk, messagebox
from storage_manager import load_all_dishes_from_file, save_all_dishes_to_file

# 定义口味和荤素类型选项
TASTE_OPTIONS = ["辣", "微辣", "不辣", "甜", "酸", "咸鲜", "其他"]
TYPE_OPTIONS = ["荤菜", "素菜", "半荤半素", "甜品"]

# 格式化菜品信息用于显示
def format_dish_for_display(dish_dict):
    """
    将菜品信息格式化为字符串，方便显示。
    :param dish_dict: 菜品信息字典
    :return: 格式化后的字符串
    """
    return (f"菜品名称：{dish_dict['name']}\n"
            f"主要食材：{dish_dict['main_ingredients']}\n"
            f"口味：{', '.join(dish_dict['taste'])}\n"
            f"荤素：{dish_dict['type']}\n"
            f"所属窗口：{dish_dict['canteen_window'] if dish_dict['canteen_window'] else '无'}")

# 加载所有菜品
all_dishes = load_all_dishes_from_file()

# 创建主窗口
root = tk.Tk()
root.title("食堂菜品管理系统")
root.geometry("900x700")  # 增大窗口尺寸

# 创建主框架
main_frame = ttk.Frame(root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)

# 创建标签页控件
notebook = ttk.Notebook(main_frame)
notebook.pack(fill=tk.BOTH, expand=True, pady=10)

# ============== 菜品管理标签页 ==============
manage_frame = ttk.Frame(notebook)
notebook.add(manage_frame, text="菜品管理")

# 菜品信息输入框架
input_frame = ttk.LabelFrame(manage_frame, text="菜品信息", padding="10")
input_frame.pack(fill=tk.X, expand=False, pady=5)

# 菜品名称
ttk.Label(input_frame, text="菜品名称：").grid(row=0, column=0, padx=5, pady=5, sticky=tk.E)
name_entry = ttk.Entry(input_frame, width=30)
name_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

# 主要食材
ttk.Label(input_frame, text="主要食材：").grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)
ingredients_entry = ttk.Entry(input_frame, width=30)
ingredients_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)

# 口味
ttk.Label(input_frame, text="口味：").grid(row=2, column=0, padx=5, pady=5, sticky=tk.E)
taste_frame = ttk.Frame(input_frame)
taste_frame.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W)
taste_vars = []
for idx, option in enumerate(TASTE_OPTIONS):
    var = tk.IntVar()
    ttk.Checkbutton(taste_frame, text=option, variable=var).grid(row=0, column=idx, padx=2)
    taste_vars.append(var)

# 荤素类型
ttk.Label(input_frame, text="荤素类型：").grid(row=3, column=0, padx=5, pady=5, sticky=tk.E)
type_var = tk.StringVar()
type_var.set(TYPE_OPTIONS[0])
type_menu = ttk.Combobox(input_frame, textvariable=type_var, values=TYPE_OPTIONS, state="readonly")
type_menu.grid(row=3, column=1, padx=5, pady=5, sticky=tk.W)

# 所属窗口
ttk.Label(input_frame, text="所属窗口：").grid(row=4, column=0, padx=5, pady=5, sticky=tk.E)
window_var = tk.StringVar()
window_var.set("川湘风味窗口")
window_menu = ttk.Combobox(input_frame, textvariable=window_var,
                           values=["川湘风味窗口", "家常菜窗口", "西餐厅", "无"],
                           state="readonly")
window_menu.grid(row=4, column=1, padx=5, pady=5, sticky=tk.W)

# 查找/修改/删除框架
query_frame = ttk.LabelFrame(manage_frame, text="查找/修改/删除", padding="10")
query_frame.pack(fill=tk.X, expand=False, pady=5)

ttk.Label(query_frame, text="菜品名称或ID：").grid(row=0, column=0, padx=5, pady=5, sticky=tk.E)
query_entry = ttk.Entry(query_frame, width=30)
query_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

# 管理按钮
button_frame = ttk.Frame(manage_frame)
button_frame.pack(fill=tk.X, expand=False, pady=10)

# 获取菜品详细信息的函数
def get_dish_details_input():
    """
    从输入框中获取菜品详细信息。
    :return: 菜品信息字典
    """
    name = name_entry.get()
    main_ingredients = ingredients_entry.get()
    taste = []
    for idx, var in enumerate(taste_vars):
        if var.get():
            taste.append(TASTE_OPTIONS[idx])
    food_type = type_var.get()
    canteen_window = window_var.get()
    if canteen_window == "无":
        canteen_window = None
    dish_id = ''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
    return {
        "dish_id": dish_id,
        "name": name,
        "main_ingredients": main_ingredients,
        "taste": taste,
        "type": food_type,
        "canteen_window": canteen_window
    }

# 清除所有输入框内容
def clear_all_entries():
    """
    清除所有输入框的内容。
    """
    name_entry.delete(0, tk.END)
    ingredients_entry.delete(0, tk.END)
    query_entry.delete(0, tk.END)
    type_var.set(TYPE_OPTIONS[0])
    window_var.set("川湘风味窗口")
    for var in taste_vars:
        var.set(0)

# 检查菜品名称是否已存在
def check_duplicate_name(name):
    """
    检查菜品名称是否已存在。
    :param name: 菜品名称
    :return: 如果存在返回 True，否则返回 False
    """
    for dish in all_dishes:
        if dish['name'] == name:
            return True
    return False

# 添加新菜品
def add_new_dish():
    """
    添加新菜品。
    """
    name = name_entry.get()
    if not name:
        messagebox.showwarning("警告", "菜品名称不能为空！")
        return

    # 检查菜品名称是否已存在
    if check_duplicate_name(name):
        messagebox.showwarning("警告", f"菜品名称 '{name}' 已存在！")
        return

    new_dish = get_dish_details_input()
    all_dishes.append(new_dish)
    save_all_dishes_to_file(all_dishes)
    messagebox.showinfo("提示", "菜品添加成功！")
    view_all_dishes()
    clear_all_entries()  # 清除输入框

# 根据名称或ID查找菜品
def find_dish_by_name_or_id(query):
    """
    根据名称或ID查找菜品。
    :param query: 菜品名称或ID
    :return: 找到的菜品和索引，如果没有找到返回 None 和 -1
    """
    found_dishes = [dish for dish in all_dishes if dish['name'] == query or dish['dish_id'] == query]
    if len(found_dishes) == 1:
        return found_dishes[0], all_dishes.index(found_dishes[0])
    elif len(found_dishes) > 0:
        # 如果找到多个，弹出选择对话框
        selection_window = tk.Toplevel(root)
        selection_window.title("选择菜品")
        selection_window.geometry("400x300")

        ttk.Label(selection_window, text="找到多个匹配的菜品，请选择：").pack(pady=10)

        listbox = tk.Listbox(selection_window, width=50)
        listbox.pack(pady=10, fill=tk.BOTH, expand=True)

        for i, dish in enumerate(found_dishes):
            listbox.insert(i, dish['name'])

        selected_index = -1

        def on_select():
            nonlocal selected_index
            selection = listbox.curselection()
            if selection:
                selected_index = selection[0]
                selection_window.destroy()

        ttk.Button(selection_window, text="确定", command=on_select).pack(pady=10)

        root.wait_window(selection_window)

        if selected_index >= 0:
            return found_dishes[selected_index], all_dishes.index(found_dishes[selected_index])
    return None, -1


# 修改菜品信息
def modify_dish_details():
    """在独立窗口中修改菜品信息"""
    query = query_entry.get()
    if not query:
        messagebox.showwarning("警告", "请输入要修改的菜品名称或ID！")
        return

    dish, index = find_dish_by_name_or_id(query)
    if not dish:
        messagebox.showinfo("提示", "未找到匹配的菜品！")
        return

    # 创建独立的修改窗口
    modify_window = tk.Toplevel(root)
    modify_window.title(f"修改菜品: {dish['name']}")
    modify_window.geometry("500x400")
    modify_window.resizable(False, False)

    # 创建主框架
    frame = ttk.Frame(modify_window, padding="20")
    frame.pack(fill=tk.BOTH, expand=True)

    # 菜品名称
    ttk.Label(frame, text="菜品名称：").grid(row=0, column=0, padx=5, pady=10, sticky=tk.E)
    name_var = tk.StringVar(value=dish['name'])
    name_entry = ttk.Entry(frame, textvariable=name_var, width=30)
    name_entry.grid(row=0, column=1, padx=5, pady=10, sticky=tk.W)

    # 主要食材
    ttk.Label(frame, text="主要食材：").grid(row=1, column=0, padx=5, pady=10, sticky=tk.E)
    ingredients_var = tk.StringVar(value=dish['main_ingredients'])
    ingredients_entry = ttk.Entry(frame, textvariable=ingredients_var, width=30)
    ingredients_entry.grid(row=1, column=1, padx=5, pady=10, sticky=tk.W)

    # 口味
    ttk.Label(frame, text="口味：").grid(row=2, column=0, padx=5, pady=10, sticky=tk.E)
    taste_frame = ttk.Frame(frame)
    taste_frame.grid(row=2, column=1, padx=5, pady=10, sticky=tk.W)

    taste_vars = []
    for idx, option in enumerate(TASTE_OPTIONS):
        var = tk.IntVar(value=1 if option in dish['taste'] else 0)
        ttk.Checkbutton(taste_frame, text=option, variable=var).grid(row=0, column=idx, padx=2)
        taste_vars.append(var)

    # 荤素类型
    ttk.Label(frame, text="荤素类型：").grid(row=3, column=0, padx=5, pady=10, sticky=tk.E)
    type_var = tk.StringVar(value=dish['type'])
    type_menu = ttk.Combobox(frame, textvariable=type_var, values=TYPE_OPTIONS, state="readonly")
    type_menu.grid(row=3, column=1, padx=5, pady=10, sticky=tk.W)

    # 所属窗口
    ttk.Label(frame, text="所属窗口：").grid(row=4, column=0, padx=5, pady=10, sticky=tk.E)
    window_var = tk.StringVar(value=dish['canteen_window'] or "无")
    window_menu = ttk.Combobox(
        frame,
        textvariable=window_var,
        values=["川湘风味窗口", "家常菜窗口", "西餐厅", "无"],
        state="readonly"
    )
    window_menu.grid(row=4, column=1, padx=5, pady=10, sticky=tk.W)

    # 错误提示标签
    error_var = tk.StringVar()
    error_label = ttk.Label(frame, textvariable=error_var, foreground="red")
    error_label.grid(row=5, column=0, columnspan=2, pady=5)

    # 确认修改
    def confirm_modify():
        new_name = name_var.get().strip()

        # 检查必填字段
        if not new_name:
            error_var.set("菜品名称不能为空！")
            return

        # 检查名称唯一性（排除当前菜品）
        if new_name != dish['name'] and check_duplicate_name(new_name):
            error_var.set(f"菜品名称 '{new_name}' 已存在！")
            return

        # 获取修改后的菜品信息
        new_taste = []
        for idx, var in enumerate(taste_vars):
            if var.get():
                new_taste.append(TASTE_OPTIONS[idx])

        new_window = window_var.get()
        if new_window == "无":
            new_window = None

        # 更新菜品数据
        all_dishes[index] = {
            "dish_id": dish['dish_id'],  # 保持原ID不变
            "name": new_name,
            "main_ingredients": ingredients_var.get(),
            "taste": new_taste,
            "type": type_var.get(),
            "canteen_window": new_window
        }

        # 保存数据并关闭窗口
        save_all_dishes_to_file(all_dishes)
        messagebox.showinfo("成功", "菜品修改成功！")
        view_all_dishes()  # 刷新主界面
        modify_window.destroy()

    # 按钮框架
    btn_frame = ttk.Frame(modify_window)
    btn_frame.pack(fill=tk.X, pady=20)

    ttk.Button(btn_frame, text="确认修改", command=confirm_modify).pack(side=tk.LEFT, padx=10)
    ttk.Button(btn_frame, text="取消", command=modify_window.destroy).pack(side=tk.LEFT)

    # 窗口置顶
    modify_window.transient(root)
    modify_window.grab_set()
    root.wait_window(modify_window)

# 删除菜品
def delete_dish():
    """
    删除菜品。
    """
    query = query_entry.get()
    if not query:
        messagebox.showwarning("警告", "请输入要删除的菜品名称或ID！")
        return
    dish, index = find_dish_by_name_or_id(query)
    if dish:
        if messagebox.askyesno("确认删除", f"确定要删除菜品 '{dish['name']}' 吗？"):
            del all_dishes[index]
            save_all_dishes_to_file(all_dishes)
            messagebox.showinfo("提示", "菜品已删除！")
            view_all_dishes()
            clear_all_entries()  # 清除输入框
    else:
        messagebox.showinfo("提示", "未找到匹配的菜品！")

# 管理按钮
ttk.Button(button_frame, text="添加菜品", command=add_new_dish).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="修改菜品", command=modify_dish_details).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="删除菜品", command=delete_dish).pack(side=tk.LEFT, padx=5)

# ============== 菜品推荐标签页 ==============
recommend_frame = ttk.Frame(notebook)
notebook.add(recommend_frame, text="菜品推荐")

# 推荐条件框架
recommend_condition_frame = ttk.LabelFrame(recommend_frame, text="推荐条件", padding="10")
recommend_condition_frame.pack(fill=tk.X, expand=False, pady=5)

# 辣度偏好
ttk.Label(recommend_condition_frame, text="辣度偏好：").grid(row=0, column=0, padx=5, pady=5, sticky=tk.E)
spicy_var = tk.StringVar()
spicy_var.set("随便")
spicy_menu = ttk.Combobox(recommend_condition_frame, textvariable=spicy_var,
                          values=["随便", "辣", "微辣", "不辣"],
                          state="readonly")
spicy_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

# 荤素偏好
ttk.Label(recommend_condition_frame, text="荤素偏好：").grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)
food_type_var = tk.StringVar()
food_type_var.set("随便")
food_type_menu = ttk.Combobox(recommend_condition_frame, textvariable=food_type_var,
                              values=["随便", "荤菜", "素菜", "半荤半素", "甜品"],
                              state="readonly")
food_type_menu.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)

# 随机推荐菜品
def get_random_recommendations(filtered_dishes, count=1):
    """
    从筛选后的菜品中随机选择指定数量的菜品。
    :param filtered_dishes: 筛选后的菜品列表
    :param count: 需要选择的菜品数量
    :return: 随机选择的菜品列表
    """
    if len(filtered_dishes) < count:
        count = len(filtered_dishes)
    return random.sample(filtered_dishes, count)

# 根据偏好筛选菜品
def filter_dishes_by_preferences(preferences):
    """
    根据用户偏好筛选菜品。
    :param preferences: 用户偏好字典
    :return: 筛选后的菜品列表
    """
    filtered = []
    for dish in all_dishes:
        # 处理辣度逻辑
        if preferences["spicy"] != "随便":
            if preferences["spicy"] == "辣" and not "辣" in dish["taste"]:
                continue
            if preferences["spicy"] == "微辣" and not ("微辣" in dish["taste"] or "辣" in dish["taste"]):
                continue
            if preferences["spicy"] == "不辣" and ("辣" in dish["taste"] or "微辣" in dish["taste"]):
                continue

        # 处理荤素类型
        if preferences["food_type"] != "随便" and dish["type"] != preferences["food_type"]:
            continue

        filtered.append(dish)
    return filtered

# 推荐菜品
def recommend_dishes():
    """
    根据用户偏好推荐菜品。
    """
    preferences = {
        "spicy": spicy_var.get(),
        "food_type": food_type_var.get()
    }
    filtered_dishes = filter_dishes_by_preferences(preferences)
    result_text.delete(1.0, tk.END)
    if not filtered_dishes:
        result_text.insert(tk.END, "没有找到符合条件的菜品，请调整筛选条件！")
        return

    count = min(5, len(filtered_dishes))  # 最多推荐5个菜品
    recommendations = get_random_recommendations(filtered_dishes, count)

    result_text.insert(tk.END, f"为您推荐以下 {len(recommendations)} 个菜品：\n\n")
    for i, dish in enumerate(recommendations, 1):
        result_text.insert(tk.END, f"【推荐 {i}】\n{format_dish_for_display(dish)}\n\n")

# 推荐按钮
ttk.Button(recommend_frame, text="获取推荐", command=recommend_dishes).pack(pady=10)

# ============== 筛选菜品标签页 ==============
filter_frame = ttk.Frame(notebook)
notebook.add(filter_frame, text="筛选菜品")

# 筛选条件框架
filter_condition_frame = ttk.LabelFrame(filter_frame, text="筛选条件", padding="10")
filter_condition_frame.pack(fill=tk.X, expand=False, pady=5)

# 筛选类型
ttk.Label(filter_condition_frame, text="筛选类型：").grid(row=0, column=0, padx=5, pady=5, sticky=tk.E)
filter_type_var = tk.StringVar()
filter_type_var.set("口味")
filter_type_menu = ttk.Combobox(filter_condition_frame, textvariable=filter_type_var,
                                values=["口味", "食材", "荤素", "窗口"],
                                state="readonly")
filter_type_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

# 筛选关键词
ttk.Label(filter_condition_frame, text="关键词：").grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)
filter_keyword_entry = ttk.Entry(filter_condition_frame, width=30)
filter_keyword_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)

# 按条件筛选菜品
def filter_dishes():
    """
    根据用户输入的条件筛选菜品。
    """
    filter_type = filter_type_var.get()
    keyword = filter_keyword_entry.get().strip()

    if not keyword:
        messagebox.showwarning("警告", "请输入筛选关键词！")
        return

    filtered = []
    if filter_type == "口味":
        filtered = [dish for dish in all_dishes if keyword in dish["taste"]]
    elif filter_type == "食材":
        filtered = [dish for dish in all_dishes if keyword in dish["main_ingredients"]]
    elif filter_type == "荤素":
        filtered = [dish for dish in all_dishes if dish["type"] == keyword]
    elif filter_type == "窗口":
        filtered = [dish for dish in all_dishes if dish["canteen_window"] == keyword]

    result_text.delete(1.0, tk.END)
    if not filtered:
        result_text.insert(tk.END, f"没有找到 {filter_type} 为 '{keyword}' 的菜品！")
        return

    result_text.insert(tk.END, f"找到 {len(filtered)} 个符合条件的菜品：\n\n")
    for i, dish in enumerate(filtered, 1):
        result_text.insert(tk.END, f"【菜品 {i}】\n{format_dish_for_display(dish)}\n\n")

# 筛选按钮
ttk.Button(filter_frame, text="筛选菜品", command=filter_dishes).pack(pady=10)

# ============== 结果显示区域 ==============
result_frame = ttk.LabelFrame(main_frame, text="结果显示", padding="10")
result_frame.pack(fill=tk.BOTH, expand=True, pady=10)

# 查看所有菜品
def view_all_dishes():
    """
    查看所有菜品。
    """
    result_text.delete(1.0, tk.END)
    if not all_dishes:
        result_text.insert(tk.END, "暂无菜品信息！")
        return

    result_text.insert(tk.END, f"共有 {len(all_dishes)} 个菜品：\n\n")
    for i, dish in enumerate(all_dishes, 1):
        result_text.insert(tk.END, f"【菜品 {i}】\n{format_dish_for_display(dish)}\n\n")

# 结果文本框 - 增大尺寸
result_text = tk.Text(result_frame, height=25, width=100, wrap=tk.WORD)  # 增大高度和宽度
result_text.pack(fill=tk.BOTH, expand=True)

# 添加滚动条
scrollbar = ttk.Scrollbar(result_text, command=result_text.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
result_text.config(yscrollcommand=scrollbar.set)

# 在主窗口底部添加状态栏
status_var = tk.StringVar()
status_var.set(f"已加载 {len(all_dishes)} 个菜品")
status_bar = ttk.Label(root, textvariable=status_var, relief=tk.SUNKEN, anchor=tk.W)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)

# 查看所有菜品按钮
ttk.Button(main_frame, text="查看所有菜品", command=view_all_dishes).pack(pady=5)

# 运行主循环
root.mainloop()